Conversation
nathanBurg
self-requested a review
April 17, 2026 02:39
nathanBurg
approved these changes
Apr 17, 2026
nathanBurg
left a comment
Contributor
There was a problem hiding this comment.
Looks good to merge once conflicts resolved!
jlitola
force-pushed
the
blue-year
branch
2 times, most recently
from
April 20, 2026 06:12
fc72028 to
886cae9
Compare
Adds GitHits' code-navigation surface behind the `code_navigation`
capability gate: a CLI command `githits code search <package>
[query]` and the MCP tool `search_symbols`, both backed by the
configured code-navigation endpoint. Finds functions, classes,
modules, and doc sections inside any indexed dependency by
exact-token search and returns source chunks with line ranges,
symbol kind, and category. The gate remains — this is a feature-
flagged rollout, not a public launch.
## CLI
`githits code search` with `search-symbols` retained as a
Commander alias. Package spec is `<registry>:<name>[@<version>]`
(npm default; nine registries supported; scoped npm names
preserved). Options:
- `--category <callable|type|module|data|documentation>` — broad
filter, the preferred surface.
- `--kind <kind>` — precise-construct filter over the full
27-value taxonomy (function, method, trait, namespace, record,
struct, enum, protocol, etc.). Prefer `--category` for most
cases.
- `--intent <intent|all>` — file intent, defaults to `production`
so top results are production source; `all` opts back into
tests/benchmarks/examples.
- `--wait <seconds>` — max indexing wait (0–60; default 20, above
backend p50). Accepts `10` or `10s`; rejects `10ms`.
- `--keywords "a,b,c"` + repeatable `--keyword <w>` — merged,
deduplicated, capped at 20 client-side.
- `--match-mode <or|and>`, `--file <prefix>`, `--limit <n>`
(1–50, default 25), `--json`.
Terminal output leads each entry with `path:startLine-endLine
[kind]`, followed by the symbol name and a 3-line dedented
snippet from the `code` field. Commit-SHA refs truncate to 7
chars; trivial `v`-prefix differences on the `(requested X)`
annotation are suppressed; the literal `[fallback]` label on
unclassified chunks is suppressed. Zero-result output surfaces
the backend hint verbatim, falling back to filter-adaptive
client suggestions. All enum values accepted case-insensitively.
## MCP tool
`search_symbols`. Wire shape identical to the CLI `--json`
envelope; deep-equal enforced by a shared parity test across
five fixtures (success, zero-result, NOT_FOUND, INDEXING,
INVALID_ARGUMENT). Error results always valid JSON in
`content[0].text`. Tool description positions `category` as the
preferred filter and documents the INDEXING retry pattern (retry
with `wait_timeout_ms: 60000`).
## Shared source-of-truth helpers
- `src/shared/code-navigation-defaults.ts` —
DEFAULT_WAIT_TIMEOUT_MS (20s), MAX_WAIT_TIMEOUT_MS (60s
ceiling), SEARCH_SYMBOLS_DEFAULT_FILE_INTENT ("PRODUCTION"),
FILE_INTENT_ALL sentinel that translates to "omit the GraphQL
variable" at the service layer.
- `src/shared/search-symbols-request.ts` —
buildSearchSymbolsParams with a `defaulted: [...]` echo so
agents see which fields the client filled in silently.
- `src/shared/search-symbols-response.ts` — success/error envelope
builders. No underscore-prefixed keys; `retryable` top-level on
errors for agents that want one boolean over a per-code table.
- `src/shared/code-navigation-error-map.ts` — single classifier
for the 13-code MappedError union
(NOT_FOUND, VERSION_NOT_FOUND, INDEXING, UNRESOLVABLE,
ACCESS_DENIED, AUTH_REQUIRED, NETWORK, INVALID_ARGUMENT,
BACKEND_ERROR, TIMEOUT, RATE_LIMITED, PROTOCOL_ERROR, UNKNOWN).
Table-tested; no UNKNOWN on any recognised error class.
- `src/shared/package-spec.ts` — hardened parser: rejects unknown
registry prefixes (`foobar:baz`), malformed specs, preserves
scoped npm names.
- `src/shared/normalise-keywords.ts` — comma + repeated-flag
merger with cap enforcement.
- `src/shared/debug-log.ts` — `GITHITS_DEBUG`-gated stderr
diagnostics. PII policy: codes, detail keys, error class names;
never message text, tokens, or response bodies.
## Service layer
Always requests `mode: DETAILED`; always selects `code`,
`resolution`, `kind`, and `category`. Nullable `data` and
`searchSymbols` accepted in the Zod response schema. `fetch()`
wrapped so connectivity failures surface as
`CodeNavigationNetworkError`. Full dispatch on `extensions.code`
covering the backend's 14 error codes, with `extensions.retryable`
propagated end-to-end. The legacy `chunkType` field is no longer
selected or surfaced client-side; `kind` is the single source of
truth (the backend handles its own chunk-to-symbol fallback
internally). Message-text heuristics retained as a rollover
fallback for backends that predate the structured error codes.
## Docs
- New `docs/implementation/mcp-cli-parity.md` — rules for
dual-surface tools (PARITY-NAMING, PARITY-DEFAULTS,
PARITY-REQUEST, PARITY-JSON-KEYS, PARITY-ERROR-ENVELOPE) with
stable rule IDs cited by the parity test.
- `docs/implementation/tools.md`,
`docs/implementation/cli-commands.md`,
`docs/implementation/config.md` updated with the new command,
response shape, and troubleshooting notes (including
`GITHITS_DEBUG=code-nav`).
- `tools.md` carries a "Pending backend follow-ups" note for the
single remaining backend-side task (distinguishing
totalMatches from returnedCount and adding an offset arg for
pagination).
## Tests
547 passing across 41 files. Highlights:
- Classifier table covers every MappedErrorCode with fixtures
for both `extensions.code` dispatch and legacy message-text
fallback.
- Parity test asserts CLI `--json` and MCP `content[0].text`
produce deep-equal JSON for the same inputs across five
fixture cases.
- Service tests exercise the full GraphQL response surface:
null data, VERSION_NOT_FOUND with structured details, TIMEOUT
/ RATE_LIMITED retryable dispatch, extensions.code-takes-
precedence over message heuristics, legacy message fallback
for pre-deploy backends.
- CLI tests cover every option: `--category`, the expanded
`--kind` taxonomy, `--wait` seconds + `s` suffix + rejection
of `ms`, keyword merge + dedup + cap, case-insensitive enum
values, zero-result adaptive suggestions, capability-gate
registration.
- Debug-log test asserts PII policy (no `message` field in
payloads) and scope-syntax parsing.
Supersedes the earlier gated code-navigation PoC that was
scaffolded under a feature flag — the capability gate remains
(commands only register when the startup token advertises
`code_navigation`, when `GITHITS_CODE_NAVIGATION=1` is set
locally, when an opaque `GITHITS_API_TOKEN` is present, or when
stored auth has expired), but the implementation underneath is
now the production surface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
codeCLI command group and the MCPsearch_symbolstool. Finds functions, classes, modules, and doc sections inside any indexed dependency by exact-token search; returns source chunks with line ranges, symbol kind, and category.--categorybroad filter (callable/type/module/data/documentation) and a 27-value--kindprecise filter. Defaults to--intent productionso top results are production source;--intent allopts back into tests / benchmarks / examples.--jsonand MCPcontent[0].text, enforced by a deep-equal parity test across five fixtures (success, zero-result, NOT_FOUND, INDEXING, INVALID_ARGUMENT). Errors always return valid JSON with a stablecode(13-value taxonomy) and a top-levelretryableflag.GITHITS_DEBUG=code-navemits PII-safe stderr diagnostics for error paths.codeCLI registers only when the startup token advertisescode_navigation, whenGITHITS_CODE_NAVIGATION=1is set locally, when an opaqueGITHITS_API_TOKENis present, or when stored auth has expired. MCP tool registration is stricter (capability advertised, or"unknown"+ opaque env token). The gate will be removed in a follow-up once the feature is ready for public rollout.Verification
bun test— 547 pass across 41 filesbun run typecheck— cleanbun run build— cleannpm:@types/node), and pinned versions (pypi:requests@2.32.3). Covers happy path, zero-result hint pass-through, VERSION_NOT_FOUND envelope, INDEXING retry guidance,--category/--kindfilters,--intent allsugar, debug logginggithits code search --helpandgithits code --helprender the new options; no "experimental", "PoC", or internal backend-service names appear in user-facing surfacesArchitecture
Shared source-of-truth helpers under
src/shared/are imported by both the CLI command and the MCP tool, so defaults, request construction, error classification, and JSON envelope shape cannot drift:code-navigation-defaults.ts— canonical timeouts +FILE_INTENT_ALLsentinelsearch-symbols-request.ts—buildSearchSymbolsParamswith adefaulted: [...]echosearch-symbols-response.ts— success / error envelope builderscode-navigation-error-map.ts— classifier for the 13-code MappedError unionpackage-spec.ts— hardened parser (rejects unknown registry prefixes, preserves scoped npm names)debug-log.ts—GITHITS_DEBUG-gated diagnosticsThe parity rules are codified in
docs/implementation/mcp-cli-parity.mdwith stable rule IDs (PARITY-NAMING,PARITY-DEFAULTS,PARITY-REQUEST,PARITY-JSON-KEYS,PARITY-ERROR-ENVELOPE) cited by the parity test.Known follow-ups
totalMatchesfromreturnedCountand adding anoffsetargument for real pagination. Until it lands, the CLI header stays atN match(es) (more available)and no--offsetflag is exposed. Tracked indocs/implementation/tools.mdunder "Pending backend follow-ups".